# coding=utf-8
'''
Created on Jun 16, 2009

@license: License: LGPL
@copyright: (c) 2009, dogsing.cn
@author: ant-man
'''

from cn.pigersing.moc.lang.mocObject import MocRuntimeException

class MocReferToDeadInstance(MocRuntimeException):pass

class MocInstanceHasExists(MocRuntimeException):pass

class MocContext(object):
    '''
    classdocs
    '''


    def __init__(self, parent=None, inst_list=None, ctx=None):
        '''
        Constructor
        '''
        self.parent = parent
        self.inst_list = inst_list if inst_list else parent.inst_list
        self.ctx = {} if not ctx else ctx
        self.sealed = {}

    def get(self, symbol):

        ret = self.ctx.get(symbol, None)
        if ret :
            try:
                return self.inst_list[ret]
            except KeyError :
                raise MocReferToDeadInstance("'%s' is a dead instance or undefined instance " % symbol)
        else :
            if not self.parent :
                return None
            ret = self.parent.get(symbol)
            # if the RET is get from its parent, maybe this symbol will be used in a closure
            # so we save it in sealed dictionary
            if ret :
                self.sealed_update(symbol, ret)
                return ret
            else :
                return None


    def set(self, symbol, value):
        if symbol in self.ctx :
            raise MocInstanceHasExists("the symbol of '%s' has already used" % symbol)
        self.ctx[symbol] = value.id

    def sealed_update(self, symbol, value):
        """
        
        @param symbol: symbol name appearing in callable context
        @param value: instance of symbol
        """
        if not (symbol in self.ctx or symbol in self.sealed) :
            self.sealed[symbol] = value.id
            # notify the parent to save the sealed symbol
            self.parent.sealed_update(symbol, value)

